package cn.broadsense.biz.service.impl;

import cn.broadsense.biz.domain.ItemTag;
import cn.broadsense.biz.domain.ItemTagTemplateDetails;
import cn.broadsense.biz.service.ItemTagService;
import cn.broadsense.biz.service.ItemTagTemplateDetailsService;
import cn.broadsense.biz.vo.ItemTagTemplateVo;
import cn.broadsense.common.exception.ServiceException;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.broadsense.biz.domain.ItemTagTemplate;
import cn.broadsense.biz.service.ItemTagTemplateService;
import cn.broadsense.biz.mapper.ItemTagTemplateMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author bs
 * @description 针对表【t_item_tag_template(事项标签模板)】的数据库操作Service实现
 * @createDate 2024-09-06 14:37:10
 */
@Service
@RequiredArgsConstructor
public class ItemTagTemplateServiceImpl extends ServiceImpl<ItemTagTemplateMapper, ItemTagTemplate>
        implements ItemTagTemplateService {

    private final ItemTagTemplateDetailsService detailsService;

    private final ItemTagService tagService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveItemTagTemplate(ItemTagTemplateVo vo) {
        ItemTagTemplate template = new ItemTagTemplate();
        template.setTemplateName(vo.getTemplateName());
        template.setTemplateSpecification(vo.getTemplateSpecification());
        template.setStatus(0);
        List<ItemTagTemplateDetails> detailsList = CollectionUtil.newArrayList();
        vo.getDetailVoList().forEach(x -> {
            ItemTagTemplateDetails details = new ItemTagTemplateDetails();
            details.setItemTagId(x.getId());
            details.setTagType(x.getTagType());
            details.setIsRequired(x.getIsRequired());
            details.setItemTagName(x.getFieldName());
            detailsList.add(details);
        });
        List<String> collect = detailsList.stream().map(ItemTagTemplateDetails::getItemTagName).collect(Collectors.toList());
        if(hasDuplicates(collect)){
            throw new ServiceException("标签名称不能重复");
        }
        assembleParams(detailsList, template);
        this.save(template);
        List<ItemTagTemplateDetails> peek = detailsList.stream().peek(x -> x.setItemTagTemplateId(template.getId())).collect(Collectors.toList());
        detailsService.saveBatch(peek);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateItemTagTemplate(ItemTagTemplate one) {
        List<ItemTagTemplateDetails> detailsList = CollectionUtil.newArrayList();
        one.getDetailVoList().forEach(x -> {
            ItemTagTemplateDetails details = new ItemTagTemplateDetails();
            details.setItemTagId(x.getId());
            details.setTagType(x.getTagType());
            details.setIsRequired(x.getIsRequired());
            details.setItemTagName(x.getFieldName());
            detailsList.add(details);
        });
        List<String> collect = detailsList.stream().map(ItemTagTemplateDetails::getItemTagName).collect(Collectors.toList());
        if(hasDuplicates(collect)){
            throw new ServiceException("标签名称不能重复");
        }
        assembleParams(detailsList, one);
        this.updateById(one);
        LambdaQueryWrapper<ItemTagTemplateDetails> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ItemTagTemplateDetails::getItemTagTemplateId, one.getId());
        detailsService.remove(wrapper);
        List<ItemTagTemplateDetails> peek = detailsList.stream().peek(x -> x.setItemTagTemplateId(one.getId())).collect(Collectors.toList());
        detailsService.saveBatch(peek);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importItemTagTemplateList(List<ItemTagTemplate> list) {
        if (CollectionUtil.isEmpty(list)) {
            throw new ServiceException("导入数据不能为空");
        }
        List<ItemTag> tags = tagService.lambdaQuery().list();
        for (int i = 0; i < list.size(); i++) {
            ItemTagTemplate template = list.get(i);
            if (StrUtil.isEmpty(template.getTemplateName())) {
                throw new ServiceException("第 " + (i + 1) + " 行模板名称不能为空");
            }
            if (StrUtil.isNotEmpty(template.getTemplateSpecification()) && template.getTemplateSpecification().length() > 200) {
                throw new ServiceException("第 " + (i + 1) + " 行模板说明不能超过200个字符");
            }
            if (StrUtil.isEmpty(template.getTagNames())) {
                throw new ServiceException("第 " + (i + 1) + " 行模板必填标签不能为空");
            }
            List<ItemTagTemplateDetails> detailsList = CollectionUtil.newArrayList();
            List<String> collect = Arrays.stream(template.getTagNames().split("、")).collect(Collectors.toList());
            if(hasDuplicates(collect)){
                throw new ServiceException("第 " + (i + 1) + " 行标签名称不能重复");
            }
            int requiredQty = 0;
            int textTagQty = 0;
            int textTagRequiredQty = 0;
            int textTagOptionalQty = 0;
            int imgTagQty = 0;
            int imgTagRequiredQty = 0;
            int imgTagOptionalQty = 0;
            int colorTagQty = 0;
            int colorTagRequiredQty = 0;
            int colorTagOptionalQty = 0;
            int iconTagQty = 0;
            int iconTagRequiredQty = 0;
            int iconTagOptionalQty = 0;
            int otherQty = 0;
            int otherRequiredQty = 0;
            int otherOptionalQty = 0;
            for (int j = 0; j < collect.size(); j++) {
                int finalJ = j;
                Optional<ItemTag> first = tags.stream().filter(x -> x.getFieldName().equals(collect.get(finalJ))).findFirst();
                if (!first.isPresent()) {
                    throw new ServiceException("第 " + (i + 1) + " 行标签 " + collect.get(j) + " 不存在");
                }
                ItemTagTemplateDetails details = new ItemTagTemplateDetails();
                details.setItemTagId(first.get().getId());
                details.setTagType(first.get().getTagType());
                details.setItemTagName(first.get().getFieldName());
                details.setIsRequired(first.get().getIsRequired());
                detailsList.add(details);
                switch (first.get().getTagType()) {
                    case 1:
                        textTagQty += 1;
                        if (first.get().getIsRequired() == 1) {
                            textTagRequiredQty += 1;
                            requiredQty += 1;
                        } else {
                            textTagOptionalQty += 1;
                        }
                        break;
                    case 2:
                        imgTagQty += 1;
                        if (first.get().getIsRequired() == 1) {
                            imgTagRequiredQty += 1;
                            requiredQty += 1;
                        } else {
                            imgTagOptionalQty += 1;
                        }
                        break;
                    case 3:
                        colorTagQty += 1;
                        if (first.get().getIsRequired() == 1) {
                            colorTagRequiredQty += 1;
                            requiredQty += 1;
                        } else {
                            colorTagOptionalQty += 1;
                        }
                        break;
                    case 4:
                        iconTagQty += 1;
                        if (first.get().getIsRequired() == 1) {
                            iconTagRequiredQty += 1;
                            requiredQty += 1;
                        } else {
                            iconTagOptionalQty += 1;
                        }
                        break;
                    case 5:
                        otherQty += 1;
                        if (first.get().getIsRequired() == 1) {
                            otherRequiredQty += 1;
                            requiredQty += 1;
                        } else {
                            otherOptionalQty += 1;
                        }
                        break;

                }
            }
            template.setRequiredQty(requiredQty);
            template.setTextTagQty(textTagQty);
            template.setTextTagRequiredQty(textTagRequiredQty);
            template.setTextTagOptionalQty(textTagOptionalQty);
            template.setImgTagQty(imgTagQty);
            template.setImgTagRequiredQty(imgTagRequiredQty);
            template.setImgTagOptionalQty(imgTagOptionalQty);
            template.setColorTagQty(colorTagQty);
            template.setColorTagRequiredQty(colorTagRequiredQty);
            template.setColorTagOptionalQty(colorTagOptionalQty);
            template.setIconTagQty(iconTagQty);
            template.setIconTagRequiredQty(iconTagRequiredQty);
            template.setIconTagOptionalQty(iconTagOptionalQty);
            template.setOtherQty(otherQty);
            template.setOtherRequiredQty(otherRequiredQty);
            template.setOtherOptionalQty(otherOptionalQty);
            this.save(template);
            List<ItemTagTemplateDetails> resultDetails = detailsList.stream().peek(x -> x.setItemTagTemplateId(template.getId())).collect(Collectors.toList());
            detailsService.saveBatch(resultDetails);

        }
    }

    public void assembleParams(List<ItemTagTemplateDetails> detailVoList, ItemTagTemplate template) {
        //必填标签数量
        List<ItemTagTemplateDetails> requiredCount = detailVoList.stream().filter(x ->x.getIsRequired() == 1).collect(Collectors.toList());
        template.setRequiredQty(requiredCount.size());
        //文字标签数量
        List<ItemTagTemplateDetails> textTag = detailVoList.stream().filter(x -> x.getTagType() == 1).collect(Collectors.toList());
        template.setTextTagQty(textTag.size());
        List<ItemTagTemplateDetails> textRequired = textTag.stream().filter(x ->x.getIsRequired() == 1).collect(Collectors.toList());
        template.setTextTagRequiredQty(textRequired.size());
        template.setTextTagOptionalQty(textTag.size() - textRequired.size());
        //图文标签数量
        List<ItemTagTemplateDetails> imgTag = detailVoList.stream().filter(x -> x.getTagType() == 2).collect(Collectors.toList());
        template.setImgTagQty(imgTag.size());
        List<ItemTagTemplateDetails> imgRequiredTag = imgTag.stream().filter(x ->x.getIsRequired() == 1).collect(Collectors.toList());
        template.setImgTagRequiredQty(imgRequiredTag.size());
        template.setImgTagOptionalQty(imgTag.size() - imgRequiredTag.size());
        //颜色标签数量
        List<ItemTagTemplateDetails> colorTag = detailVoList.stream().filter(x -> x.getTagType() == 3).collect(Collectors.toList());
        template.setColorTagQty(colorTag.size());
        List<ItemTagTemplateDetails> colorRequiredTag = colorTag.stream().filter(x ->x.getIsRequired() == 1).collect(Collectors.toList());
        template.setColorTagRequiredQty(colorRequiredTag.size());
        template.setColorTagOptionalQty(colorTag.size() - colorRequiredTag.size());
        //图标标签数量
        List<ItemTagTemplateDetails> iconTag = detailVoList.stream().filter(x -> x.getTagType() == 4).collect(Collectors.toList());
        template.setIconTagQty(iconTag.size());
        List<ItemTagTemplateDetails> iconRequiredTag = iconTag.stream().filter(x ->x.getIsRequired() == 1).collect(Collectors.toList());
        template.setIconTagRequiredQty(iconRequiredTag.size());
        template.setIconTagOptionalQty(iconTag.size() - iconRequiredTag.size());
        //其他标签数量
        List<ItemTagTemplateDetails> otherTag = detailVoList.stream().filter(x -> x.getTagType() == 5).collect(Collectors.toList());
        template.setOtherQty(otherTag.size());
        List<ItemTagTemplateDetails> otherRequiredTag = otherTag.stream().filter(x ->x.getIsRequired() == 1).collect(Collectors.toList());
        template.setOtherRequiredQty(otherRequiredTag.size());
        template.setOtherOptionalQty(otherTag.size() - otherRequiredTag.size());
    }

    public static boolean hasDuplicates(List<?> list) {
        Set<?> set = new HashSet<>(list);
        return set.size() < list.size();
    }
}




